﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework.Storage;

namespace MDXModelImporter
{   

    public class MDXParse
    {        
        public MemoryStream ms;
        public FileStream fs;
        public BinaryReader br;

	    public int	            mSize;
        public bool	            mLoaded;
        //public mdxTag           mTag;
	    public mdxCameras	    mCameras;
	    public mdxVersion	    mVersion;
        public mdxInfo          mInfo;
	    public mdxGeometry		mGeometry;
	    public mdxSequence		mSequences;
	    public mdxTextures		mTextures;
	    public mdxMaterialMap	mMaterials;
		

        public MDXParse()
        {
        }

        //.mdx file path
        public void LoadFromFile(string filename)
        {            
            try
            {
                fs = File.Open(filename, FileMode.Open);                
            }
            catch (Exception ex)
            {
                Log.Write(filename+" file not found !");
                throw ex;
            }
            mSize = (int)(fs.Length);
            if(mSize==0)
            {
                Log.Write("Error .mdx file size is 0");
                throw new Exception("Error .mdx file's size is 0");
            }
            br = new BinaryReader(fs);
            br.BaseStream.Position = 0;
            //...............
            ParseStream();

            br.Close();
            fs.Close();
        }

        //load from memory bytes
        //byte[] bytes    = File.ReadAllBytes(filename);
        public void LoadFromMemory(byte[] bytes)
        {
            mSize = bytes.Length;
            if (mSize == 0)
            {
                Log.Write("Error .mdx file size is 0");
                throw new Exception("Error .mdx file's size is 0");
            }
            // read summary of data stored in the md2 file
            ms = new MemoryStream(bytes);
            br = new BinaryReader(ms);
            ms.Position = 0;
            //.........
            ParseStream();

            br.Close();
            ms.Close();
        }				
        
        //different mdx file has different tags Check the Log file
        //footman   //VERS MODL SEQS MTLS TEXS GEOS GEOA BONE HELP ATCH PIVT EVTS CLID
        //knight    //GLBS PRE2
        protected void ParseStream()
        {           
            //it should be 'MDLX' in reverse;How to check? I don't know yet
            string tagStr = mdxTag.Read(ref br);
            if (tagStr != "MDLX")
            {
                tagStr = "Error The First Tag is " + tagStr;
                Log.Write( tagStr);
                throw new Exception(tagStr);
            }

            int chunkSize;
            long brOffeset;
            while (br.BaseStream.Position<fs.Length)
            {                
                tagStr= mdxTag.Read(ref br);               
                Log.Write(tagStr);
                switch (tagStr)
                {
                    case "BONE":
                        chunkSize = br.ReadInt32();
                        brOffeset = br.BaseStream.Position;
                        br.BaseStream.Position = brOffeset + chunkSize;
                        break;
                    
                    //case "MODL":
                    //    chunkSize = br.ReadInt32();
                    //    brOffeset = br.BaseStream.Position;
                    //    mInfo.Read(ref br, chunkSize);
                    //    br.BaseStream.Position = brOffeset + chunkSize;
                    //    break;
                    case "GEOS":
                        chunkSize = br.ReadInt32();
                        brOffeset = br.BaseStream.Position;
                        mGeometry.Read(ref br, chunkSize);
                        br.BaseStream.Position = brOffeset + chunkSize;
                        break;

                    //These Tags are useless
                    case "VERS":
                    case "MODL":
                    case "ATCH":
                    case "CAMS":
                    default:
                        chunkSize = br.ReadInt32();
                        brOffeset = br.BaseStream.Position;
                        br.BaseStream.Position = brOffeset + chunkSize;
                        //return;
                        //throw new Exception(tagStr);
                        break;

                }

            }

        }
	

        //void			Render				(void);
        //void			Load				(char* inName);
        //bool			LoadFromMemory(const char* inBuf, const long inBufSize);
    }
}
